package com.android.wnba.util.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;
import org.xmlrpc.android.IXMLRPCSerializer;
import org.xmlrpc.android.Tag;
import org.xmlrpc.android.XMLRPCException;
import org.xmlrpc.android.XMLRPCFault;
import org.xmlrpc.android.XMLRPCSerializer;

import android.content.Context;
import android.util.Xml;

import com.android.wnba.util.Constants;
import com.android.wnba.util.Util;

public class WnbaHttpClient extends MyHttpClient {

	public static final int CONNECTION_TIMEOUT = 30000;
	public static String ExtSystem = "";
	public static String ExtUser = "";

	// rpc方法
	private XmlSerializer serializer;
	private IXMLRPCSerializer iXMLRPCSerializer;

	public WnbaHttpClient(Context ctx) {
		super(ctx);
		serializer = Xml.newSerializer();
		iXMLRPCSerializer = new XMLRPCSerializer();
	}

	public WnbaResponse httpGet(String url, String queryString)
			throws Exception {
		WnbaResponse upgradeResponse = null;

		if (queryString != null && !queryString.equals("")) {
			url += "?" + queryString;
		}
		Util.debugMsg("Ext-System:" + ExtSystem);
		Util.debugMsg("Ext-User:" + ExtUser);
		DefaultHttpClient httpClient = create();
		HttpGet httpGet = new HttpGet(url);
		httpGet.addHeader("Ext-System", ExtSystem);
		httpGet.addHeader("Ext-User", ExtUser);
		httpGet.addHeader(HTTP.USER_AGENT, "oppox903");
		HttpConnectionParams.setConnectionTimeout(httpGet.getParams(),
				CONNECTION_TIMEOUT_MS);
		HttpConnectionParams.setSoTimeout(httpGet.getParams(),
				SOCKET_TIMEOUT_MS);
		httpClient.setHttpRequestRetryHandler(requestRetryHandler);

		if (isMobileActive(ctx)) { // wap代理
			HttpHost proxy;
			String proxyHost = android.net.Proxy.getDefaultHost();
			int proxyPort = android.net.Proxy.getDefaultPort();
			if (proxyHost != null) {
				proxy = new HttpHost(proxyHost, proxyPort);
				httpClient.getParams().setParameter(
						ConnRouteParams.DEFAULT_PROXY, proxy);
			}
		}

		try {
			HttpResponse response = httpClient.execute(httpGet);

			upgradeResponse = new WnbaResponse();
			upgradeResponse.statusCode = response.getStatusLine()
					.getStatusCode();
			upgradeResponse.content = EntityUtils
					.toString(response.getEntity());
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (httpClient != null && httpClient.getConnectionManager() != null) {
			httpClient.getConnectionManager().shutdown();
		}

		return upgradeResponse;
	}

	public WnbaResponse httpPost(String url, String requestBody)
			throws Exception {
		WnbaResponse upgradeResponse = null;
		DefaultHttpClient httpClient = create();
		HttpPost httpPost = new HttpPost(url);
		Util.debugMsg("Ext-System:" + ExtSystem);
		Util.debugMsg("Ext-User:" + ExtUser);
		httpPost.addHeader("Ext-System", ExtSystem);
		httpPost.addHeader("Ext-User", ExtUser);
		httpPost.addHeader(HTTP.USER_AGENT, "oppox903");
		httpPost.getParams().setParameter("http.socket.timeout",
				new Integer(CONNECTION_TIMEOUT));
		httpPost.setEntity(new StringEntity(requestBody));
		Util.debugMsg("post_url=" + url);
		Util.debugMsg("post_request=" + requestBody);
		HttpConnectionParams.setConnectionTimeout(httpPost.getParams(),
				CONNECTION_TIMEOUT_MS);
		HttpConnectionParams.setSoTimeout(httpPost.getParams(),
				SOCKET_TIMEOUT_MS);
		httpClient.setHttpRequestRetryHandler(requestRetryHandler);

		if (isMobileActive(ctx)) { // wap代理
			HttpHost proxy;
			String proxyHost = android.net.Proxy.getDefaultHost();
			int proxyPort = android.net.Proxy.getDefaultPort();
			if (proxyHost != null) {
				proxy = new HttpHost(proxyHost, proxyPort);
				httpClient.getParams().setParameter(
						ConnRouteParams.DEFAULT_PROXY, proxy);
			}
		}

		try {
			HttpResponse response = httpClient.execute(httpPost);
			if (response != null) {
				upgradeResponse = new WnbaResponse();
				int statusCode = response.getStatusLine().getStatusCode();
				upgradeResponse.statusCode = statusCode;
				if (statusCode == WnbaResponse.HTTP_OK) {
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					byte[] b = new byte[2048];
					InputStream is = response.getEntity().getContent();
					for (int i = 0; i != -1; i = is.read(b))
						baos.write(b, 0, i);
					byte[] ResponseBody = baos.toByteArray();
					upgradeResponse.content = Util.getUTF8String(ResponseBody);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (httpClient != null && httpClient.getConnectionManager() != null) {
			httpClient.getConnectionManager().shutdown();
		}
		if (upgradeResponse != null) {
			Util.debugMsg("post_statusCode=" + upgradeResponse.statusCode);
			Util.debugMsg("post_response=" + upgradeResponse.content);
		}
		return upgradeResponse;
	}

	public WnbaResponse httpPostRpc(String method, Object[] params)
			throws Exception {
		String requestBody = methodCall(method, params);

		WnbaResponse wnbaResponse = null;
		DefaultHttpClient httpClient = create();
		HttpPost httpPost = new HttpPost(Constants.URL_SERVER);
		httpPost.addHeader("Content-Type", "text/xml");
		httpPost.addHeader("Ext-System", ExtSystem);
		httpPost.addHeader("Ext-User", ExtUser);
		httpPost.getParams().setParameter("http.socket.timeout",
				new Integer(CONNECTION_TIMEOUT));
		httpPost.setEntity(new StringEntity(requestBody));
		Util.debugMsg("post_method=" + method);
		Util.debugMsg("post_request=" + requestBody);
		HttpConnectionParams.setConnectionTimeout(httpPost.getParams(),
				CONNECTION_TIMEOUT_MS);
		HttpConnectionParams.setSoTimeout(httpPost.getParams(),
				SOCKET_TIMEOUT_MS);
		httpClient.setHttpRequestRetryHandler(requestRetryHandler);

		if (isMobileActive(ctx)) { // wap代理
			HttpHost proxy;
			String proxyHost = android.net.Proxy.getDefaultHost();
			int proxyPort = android.net.Proxy.getDefaultPort();
			if (proxyHost != null) {
				proxy = new HttpHost(proxyHost, proxyPort);
				httpClient.getParams().setParameter(
						ConnRouteParams.DEFAULT_PROXY, proxy);
			}
		}

		try {
			HttpResponse response = httpClient.execute(httpPost);
			if (response != null) {
				HttpEntity entity = response.getEntity();
				wnbaResponse = new WnbaResponse();
				int statusCode = response.getStatusLine().getStatusCode();
				wnbaResponse.statusCode = statusCode;
				if (statusCode == WnbaResponse.HTTP_OK) {
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					byte[] b = new byte[2048];
					InputStream is = response.getEntity().getContent();
					Util.debug(is.toString());
					for (int i = 0; i != -1; i = is.read(b))
						baos.write(b, 0, i);
					byte[] ResponseBody = baos.toByteArray();
					wnbaResponse.content = Util.getUTF8String(ResponseBody);

					/***************** 以下xmlrpc解析 ******************/
					XmlPullParser pullParser = XmlPullParserFactory
							.newInstance().newPullParser();
					// Reader reader = new InputStreamReader(new
					// BufferedInputStream(is2));
					Reader reader = new StringReader(wnbaResponse.content);
					// for testing purposes only
					pullParser.setInput(reader);

					// lets start pulling...
					pullParser.nextTag();
					pullParser.require(XmlPullParser.START_TAG, null,
							Tag.METHOD_RESPONSE);

					pullParser.nextTag(); // either Tag.PARAMS (<params>) or
											// Tag.FAULT (<fault>)
					String tag = pullParser.getName();
					if (tag.equals(Tag.PARAMS)) {
						// normal response
						pullParser.nextTag(); // Tag.PARAM (<param>)
						pullParser.require(XmlPullParser.START_TAG, null,
								Tag.PARAM);
						pullParser.nextTag(); // Tag.VALUE (<value>)

						// deserialize result
						Object obj = iXMLRPCSerializer.deserialize(pullParser);
						entity.consumeContent();
						wnbaResponse.object = obj;
					} else if (tag.equals(Tag.FAULT)) {
						// fault response
						pullParser.nextTag(); // Tag.VALUE (<value>)

						// deserialize fault result
						Map<String, Object> map = (Map<String, Object>) iXMLRPCSerializer
								.deserialize(pullParser);
						String faultString = (String) map.get(Tag.FAULT_STRING);
						int faultCode = (Integer) map.get(Tag.FAULT_CODE);
						entity.consumeContent();
						throw new XMLRPCFault(faultString, faultCode);
					} else {
						entity.consumeContent();
						throw new XMLRPCException(
								"Bad tag <"
										+ tag
										+ "> in XMLRPC response - neither <params> nor <fault>");
					}
					/***************** 以上xmlrpc解析 ******************/
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (httpClient != null && httpClient.getConnectionManager() != null) {
			httpClient.getConnectionManager().shutdown();
		}
		if (wnbaResponse != null) {
			Util.debugMsg("post_statusCode=" + wnbaResponse.statusCode);
			Util.debugMsg("post_response=" + wnbaResponse.content);
			Util.debugMsg("post_responseObj=" + wnbaResponse.object);
		}
		return wnbaResponse;
	}

	/*********************************以下方法来自xmlrpc******************************/
	private String methodCall(String method, Object[] params)
			throws IllegalArgumentException, IllegalStateException, IOException {
		StringWriter bodyWriter = new StringWriter();
		serializer.setOutput(bodyWriter);
		serializer.startDocument(null, null);
		serializer.startTag(null, Tag.METHOD_CALL);
		// set method name
		serializer.startTag(null, Tag.METHOD_NAME).text(method)
				.endTag(null, Tag.METHOD_NAME);

		serializeParams(params);

		serializer.endTag(null, Tag.METHOD_CALL);
		serializer.endDocument();

		return bodyWriter.toString();
	}

	protected void serializeParams(Object[] params)
			throws IllegalArgumentException, IllegalStateException, IOException {
		if (params != null && params.length != 0) {
			// set method params
			serializer.startTag(null, Tag.PARAMS);
			for (int i = 0; i < params.length; i++) {
				serializer.startTag(null, Tag.PARAM).startTag(null,
						IXMLRPCSerializer.TAG_VALUE);
				iXMLRPCSerializer.serialize(serializer, params[i]);
				serializer.endTag(null, IXMLRPCSerializer.TAG_VALUE).endTag(
						null, Tag.PARAM);
			}
			serializer.endTag(null, Tag.PARAMS);
		}
	}
}
